package nth.randcats.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class RandCats implements EntryPoint {

	private static final String IMAGES_URL = "images/";
	private static final String INVALID_CREDENTIALS_IMAGE = IMAGES_URL + "rejected.jpg";
	
	private static final String LOADING_MSG = "Verifying credentials...";

	public static final String ARG_DELIMITER = "/";

	private static final String HOME_INSTRUCTIONS = "Give us the email and password you use for Facebook, and we'll give you a picture of a cat.";
	private static final String INVALID_INSTRUCTIONS = "That email and password didn't work. Try again?";
	private static final String SUCCESS_INSTRUCTIONS = "Here is your cat! Feel free to use the link to this page to share your personalized image with others.";
	private static final String SERVER_FAIL = "The server failed. Try again in a few minutes?";
	
	private static final String historyRegex = RandCatsView.EMAIL_REGEX.substring(0,
			RandCatsView.EMAIL_REGEX.length() - 1) + "/.+$";

	private static final int MAX_CAT_INDEX = 6;
	private static final String CAT_IMAGE_NAME = "cat";
	private static final String CAT_IMAGE_EXT = ".jpg";

	private final RandCatsView view = new RandCatsView();

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		History.addValueChangeHandler(new ValueChangeHandler<String>() {
			@Override
			public void onValueChange(ValueChangeEvent<String> event) {
				showCat(event.getValue());
			}
		});

		RootPanel.get("viewContainer").add(view);

		showCat(History.getToken());
	}

	protected void showCat(String historyToken) {
		if (historyToken == "" || !historyToken.matches(historyRegex)) {
			view.setInstruction(HOME_INSTRUCTIONS);
			view.hideImage();
			return;
		}

		String[] args = historyToken.split(ARG_DELIMITER);
		final String email = args[0];
		final String password = args[1];

		view.setInstruction("");
		view.hideImage();
		view.showProgressBar(LOADING_MSG);
		VerifyCredentials.Util.getInstance().isValid(email, password, new AsyncCallback<Boolean>() {

			@Override
			public void onFailure(Throwable caught) {
				view.hideProgressBar();
				onServerError();
			}

			@Override
			public void onSuccess(Boolean isValid) {
				view.hideProgressBar();
				
				if (!isValid) {
					view.setInstruction(INVALID_INSTRUCTIONS);
					view.showImage(INVALID_CREDENTIALS_IMAGE);
					return;
				}

				view.setInstruction(SUCCESS_INSTRUCTIONS);

				// GWT's Random is from the browser, which can't be
				// seeded
				RandomNumber.Util.getInstance().getRandomNumber(email, password, MAX_CAT_INDEX,
						new AsyncCallback<Integer>() {

							@Override
							public void onSuccess(Integer result) {
								final int index = result % MAX_CAT_INDEX;
								view.setInstruction(SUCCESS_INSTRUCTIONS);
								view.showImage(IMAGES_URL + CAT_IMAGE_NAME + index + CAT_IMAGE_EXT);
							}

							@Override
							public void onFailure(Throwable caught) {
								onServerError();
							}
						});
			}
		});
	}

	private void onServerError() {
		view.hideImage();
		view.setInstruction(SERVER_FAIL);
	}
}